//+--------------------------------------------------------------------------------
//| Copyright (c) 2012 - 2013 ### an.vuongngocduy
//| This file is a part of Compact Game Engine (CGE)
//+--------------------------------------------------------------------------------
#include "cgeImageTranscoderTGA.h"

namespace cge
{
	namespace gfx
	{
		//=========================================================================================
		s8 ImageTranscoderTGA::LoadImage(Stream& inStream, Image& image) const
		{
			Allocator<u8> localAlloc;
			FileHeaderTGA fileHeader;
			FileFooterTGA fileFooter;
			inStream.Seek(inStream.Size() - 26, true);
			inStream.Read((u8*)&fileFooter, 26);
			
			if(memcmp(fileFooter.Magick, "TRUEVISION-XFILE.", 18))
			{
				//TODO(an.vuong): add a warning here to notify that this maybe a corrupt TGA or old format TGA
			}
			
			image.Dispose();

			inStream.Seek(0, true);
			inStream.Read((u8*)&fileHeader, sizeof(FileHeaderTGA));

			Image::Descriptor* desc = this->lockOn(image);
			desc->Dimension.Set(fileHeader.Width, fileHeader.Height);
	
			if(fileHeader.ImageType == 2) // Unmapped RGB
			{
				u32 nSkipBytes = fileHeader.IdLen + 
					(fileHeader.ColorMap == 0) ? 0 : ( fileHeader.ColourMapSize * (fileHeader.ColourMapBits / 8));

				inStream.Seek(nSkipBytes);
				if(fileHeader.BitsPerPixel == 24) //bgra
				{
					desc->Format = PixelFormat::Bpp24_B8G8R8;
					
					desc->Data = localAlloc.Allocate(image.Size());
					if(desc->Data == null) //out of memory
						return 1;

					u8* tgaData = localAlloc.Allocate(image.Size());
					if(tgaData == null) //out of memory
						return 1;

					inStream.Read(tgaData, image.Size());

					u8 bytesPerPix = image.BitsPerPixel() / 8; 
					u32 rowSize = bytesPerPix * fileHeader.Width;

					for(u32 row = 0; row < fileHeader.Height; row++)
					{
						// pixels are stored from bottom to top and in BGR format
						u8* pData = desc->Data + (row * rowSize);
						memcpy(pData, tgaData + rowSize * (fileHeader.Height - (row + 1)),rowSize);
					
					#if 0 // turn on if store image as R8G8B8
						// swap B and R
						for(u32 col = 0; col < rowSize; col += bytesPerPix)
						{
							pData[col] = pData[col] ^ pData[col + 2];
							pData[col + 2] = pData[col] ^ pData[col + 2];
							pData[col] = pData[col] ^ pData[col + 2];
						}
					#endif
					}
				}
			}
			return 0;

		}

		//=========================================================================================
		s8 ImageTranscoderTGA::SaveImage(Stream& outStream, const Image& image) const
		{
			return 0;
		}
		
		//=========================================================================================
	}
}
